﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Mindfor.Web.Data;
using NHibernate;
using NHibernate.Linq;
using Mindfor.Web.Models;
using System.Web.Mvc;

namespace Mindfor.Web.Modules.Catalog
{
	public class CatalogModule : ModuleBase
    {
		/// <summary>
		/// Custom role name for Catalog Module.  
		/// ProductsManager can add/edit/delete categories in catalog.
		/// and add/edit/delete products to catalog.
		/// </summary>
		public const string ProductsRole = "CatalogManager";

		/// <summary>
		/// Default page size for products-index pages
		/// </summary>
		public const string IndexProductsPageSizeOption = "IndexProductsPageSize";

		/// <summary>
		/// Category view-option has two variants: list and tiles.
		/// </summary>
		public const string ShowTilesOption = "ShowTiles";

		public override string FriendlyName
		{
			get { return "Каталог"; }
		}

		public override void Register(ModuleRegistrationData info)
		{
			base.Register(info);

			// create role if one does not exist
			Role role = info.Data.Query<Role>().FirstOrDefault(r => r.Name == ProductsRole);
			if (role == null)
			{
				role = new Role()
				{
					Name = ProductsRole,
					FriendlyName = "Менеджер каталога",
					Description = "Позволяет управлять каталогом товаров и услуг"
				};
				using (ITransaction t = info.Data.BeginTransaction())
				{
					info.Data.Save(role);
					t.Commit();
				}
			}

			// create options
			bool optionsChanged = false;

			ModuleOption indexProductsPageSizeOption = Options[IndexProductsPageSizeOption];
			if (indexProductsPageSizeOption == null)
			{
			    indexProductsPageSizeOption = new ModuleOption(IndexProductsPageSizeOption, ModuleOptionType.Integer, 20, "Количество продуктов или услуг на одной странице.");
			    Options.Add(indexProductsPageSizeOption);
			    optionsChanged = true;
			}

			ModuleOption showTilesOption = Options[ShowTilesOption];
			if (showTilesOption == null)
			{
				showTilesOption = new ModuleOption(ShowTilesOption, ModuleOptionType.Boolean, false, "Отображение категорий в корневой категории: false - отображение списком (друг под другом), true - отображение плашками (последовательно в ряд).");
				Options.Add(showTilesOption);
				optionsChanged = true;
			}

			if (optionsChanged)
			    Options.Save(info.Data);
		}

		/// <summary>
		/// Performs search in module.
		/// </summary>
		/// <param name="data">Current data session.</param>
		/// <param name="url">Url helper.</param>
		/// <param name="text">Text to search.</param>
		/// <returns>Search results.</returns>
		public override IEnumerable<SearchResult> Search(ISession data, UrlHelper url, string text)
		{
			List<SearchResult> results = data.Query<Product>()
				.Where(r => r.Title.Contains(text) || r.TextShort.Contains(text) || r.TextFull.Contains(text))
				.ToList()
				.Select(r => new SearchResult(this, r.Title)
				{
					Url = url.ActionModule("Item", "Products", Name, new { id = r.Id })
				})
				.ToList();
			
			results.AddRange(
				data.Query<Category>()
					.Where(r => r.Title.Contains(text) || r.Text.Contains(text))
					.ToList()
					.Select(r => new SearchResult(this, r.Title)
					{
						Url = url.ActionModule("Index", "Products", Name, new { parentId = r.Id })
					})
					.ToList()
			);
			return results;
		}
    }
}
